package com.woniu.tool;

import com.alibaba.fastjson2.JSON;

import java.util.ArrayList;

/**
 * @author 86136
 * @version 1.0
 * @description: 还款工具类，测算利息
 * @date 2022/9/27 16:56
 */
//@Configuration
public class RefundUtil {

    /**
     * 计算等额本息还款
     *
     * @param loanAmount        贷款金额
     * @param loanTerm          贷款期限
     * @param monthlyRate       月利率
     * @param consultingFeeRate 咨询费利率
     * @param marginRate        保证金利率
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterest(double loanAmount, double loanTerm, double monthlyRate, double consultingFeeRate, double marginRate) {
        ArrayList<String> data = new ArrayList<>();
        consultingFeeRate = consultingFeeRate / 100;
        monthlyRate = monthlyRate / 100;
        marginRate = marginRate / 100;
        loanAmount = loanAmount * (1 + consultingFeeRate + marginRate);
        double preLoan = (loanAmount * monthlyRate * Math.pow((1 + monthlyRate), loanTerm)) / (Math.pow((1 + monthlyRate), loanTerm) - 1);//每月还款金额
        double totalMoney = preLoan * loanTerm;//还款总额
        double interest = totalMoney - loanAmount;//还款总利息
        data.add(FormatDecimal.format(totalMoney));//还款总额
        data.add(FormatDecimal.format(loanAmount));//贷款总额
        data.add(FormatDecimal.format(interest));//还款总利息
        data.add(FormatDecimal.format(preLoan));//每月还款金额
        data.add(String.valueOf(loanTerm));//还款期限
        return data.toArray(new String[data.size()]);
    }

    public static void main(String[] args) {
        String[] result1 = calculateEqualPrincipalAndInterest(200000, 24, 0.49, 0.1, 0.1);
        String[] result2 = calculateEqualPrincipal(1000, 24, 0.49, 0.1, 0.1);
        String[] result3 = calculateEqualPrincipalAndInterest(100000, 24, 5, 0.49, 0.1, 0.1);
        String[] result4 = calculateEqualPrincipal(100000, 24, 5, 0.49, 0.1, 0.1);
        System.out.println(JSON.toJSONString(result1));
        System.out.println(JSON.toJSONString(result2));
        System.out.println(JSON.toJSONString(result3));
        System.out.println(JSON.toJSONString(result4));

    }

    /**
     * 计算等额本金还款
     *
     * @param loanAmount        贷款金额
     * @param loanTerm          贷款期限
     * @param monthlyRate       月利率
     * @param consultingFeeRate 咨询费利率
     * @param marginRate        保证金利率
     * @return
     */
    public static String[] calculateEqualPrincipal(double loanAmount, int loanTerm, double monthlyRate, double consultingFeeRate, double marginRate) {
        ArrayList<String> data = new ArrayList<String>();
        consultingFeeRate = consultingFeeRate / 100;
        monthlyRate = monthlyRate / 100;
        marginRate = marginRate / 100;
        loanAmount = loanAmount * (1 + consultingFeeRate + marginRate);
        double prePrincipal = loanAmount / loanTerm;//每月还款本金
        double firstMonth = prePrincipal + loanAmount * monthlyRate;//第一个月还款金额
        double decreaseMonth = prePrincipal * monthlyRate;//每月利息递减
        double interest = (loanTerm + 1) * loanAmount * monthlyRate / 2;//还款总利息
        double totalMoney = loanAmount + interest;//还款总额
        data.add(FormatDecimal.format(totalMoney));//还款总额
        data.add(FormatDecimal.format(loanAmount));//贷款总额
        data.add(FormatDecimal.format(interest));//还款总利息
        data.add(FormatDecimal.format(firstMonth));//首月还款金额
        data.add(FormatDecimal.format(decreaseMonth));//每月递减利息
        data.add(String.valueOf(loanTerm));//还款期限
        return data.toArray(new String[data.size()]);
    }

    /**
     * 一次性提前还款计算（等额本息）
     *
     * @param loanAmount        贷款金额
     * @param loanTerm          贷款期限
     * @param monthlyRate       月利率
     * @param consultingFeeRate 咨询费利率
     * @param marginRate        保证金利率
     * @param payTimes          已还次数
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterest(double loanAmount, int loanTerm, int payTimes, double monthlyRate, double consultingFeeRate, double marginRate) {
        ArrayList<String> data = new ArrayList<String>();
        consultingFeeRate = consultingFeeRate / 100;
        monthlyRate = monthlyRate / 100;
        marginRate = marginRate / 100;
        loanAmount = loanAmount * (1 + consultingFeeRate + marginRate);
        double preLoan = (loanAmount * monthlyRate * Math.pow((1 + monthlyRate), loanTerm)) / (Math.pow((1 + monthlyRate), loanTerm) - 1);//每月还款金额
        double totalMoney = preLoan * loanTerm;//还款总额
        double interest = totalMoney - loanAmount;//还款总利息
        double leftLoan = loanAmount * Math.pow(1 + monthlyRate, payTimes) - preLoan * (Math.pow(1 + monthlyRate, payTimes) - 1) / monthlyRate;//n个月后欠银行的钱
        double payLoan = loanAmount - leftLoan;//已还本金
        double payTotal = preLoan * payTimes;//已还总金额
        double payInterest = payTotal - payLoan;//已还利息
        double totalPayAhead = leftLoan * (1 + monthlyRate);//剩余一次还清
        double saveInterest = totalMoney - payTotal - totalPayAhead;
        data.add(FormatDecimal.format(totalMoney));//原还款总额
        data.add(FormatDecimal.format(loanAmount));//贷款总额
        data.add(FormatDecimal.format(interest));//原还款总利息
        data.add(FormatDecimal.format(preLoan));//原还每月还款金额
        data.add(FormatDecimal.format(payTotal));//已还总金额
        data.add(FormatDecimal.format(payLoan));//已还本金
        data.add(FormatDecimal.format(payInterest));//已还利息
        data.add(FormatDecimal.format(totalPayAhead));//一次还清支付金额
        data.add(FormatDecimal.format(saveInterest));//节省利息
        return data.toArray(new String[data.size()]);
    }

    /**
     * 一次性提前还款计算(等额本金)
     *
     * @param loanAmount        贷款金额
     * @param loanTerm          贷款期限
     * @param monthlyRate       月利率
     * @param consultingFeeRate 咨询费利率
     * @param marginRate        保证金利率
     * @param payTimes          已还次数
     * @return
     */
    public static String[] calculateEqualPrincipal(double loanAmount, int loanTerm, int payTimes, double monthlyRate, double consultingFeeRate, double marginRate) {
        ArrayList<String> data = new ArrayList<String>();
        consultingFeeRate = consultingFeeRate / 100;
        monthlyRate = monthlyRate / 100;
        marginRate = marginRate / 100;
        loanAmount = loanAmount * (1 + consultingFeeRate + marginRate);
        double prePrincipal = loanAmount / loanTerm;//每月还款本金
        double firstMonth = prePrincipal + loanAmount * monthlyRate;//第一个月还款金额
        double decreaseMonth = prePrincipal * monthlyRate;//每月利息递减
        double interest = (loanTerm + 1) * loanAmount * monthlyRate / 2;//还款总利息
        double totalMoney = loanAmount + interest;//还款总额
        double payLoan = prePrincipal * payTimes;//已还本金
        double payInterest = (loanAmount * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthlyRate;//已还利息
        double payTotal = payLoan + payInterest;//已还总额
        double totalPayAhead = (loanAmount - payLoan) * (1 + monthlyRate);//提前还款金额（剩余本金加上剩余本金当月利息）
        double saveInterest = totalMoney - payTotal - totalPayAhead;
        data.add(FormatDecimal.format(totalMoney));//原还款总额
        data.add(FormatDecimal.format(loanAmount));//贷款总额
        data.add(FormatDecimal.format(interest));//原还款总利息
        data.add(FormatDecimal.format(firstMonth));//原首月还款金额
        data.add(FormatDecimal.format(decreaseMonth));//原每月递减利息
        data.add(FormatDecimal.format(payTotal));//已还总金额
        data.add(FormatDecimal.format(payLoan));//已还本金
        data.add(FormatDecimal.format(payInterest));//已还利息
        data.add(FormatDecimal.format(totalPayAhead));//一次还清支付金额
        data.add(FormatDecimal.format(saveInterest));//节省利息
        data.add(String.valueOf(0));//剩余还款期限
        return data.toArray(new String[data.size()]);
    }
}
